home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / prog / graphics / convex_hull.c < prev    next >
C/C++ Source or Header  |  1994-08-05  |  3KB  |  177 lines

  1. #include <LEDA/plane.h>
  2. #include <LEDA/graph.h>
  3. #include <LEDA/window.h>
  4.  
  5.  
  6. struct p_edge {
  7.  
  8. segment   s;
  9. list_item it;
  10.  
  11. };
  12.  
  13. typedef p_edge* p_edge_ptr;
  14.  
  15.  
  16.  
  17.  
  18. GRAPH<p_edge_ptr,int> DAG;
  19. list<node>            POL;
  20.  
  21.  
  22.  
  23. node NEW_NODE(segment s)
  24. { p_edge_ptr p = new p_edge;
  25.   p->s =s;
  26.   return DAG.new_node(p);
  27.  }
  28.  
  29.  
  30.  
  31.  
  32. node next_segment(segment s, node v )
  33. { node u = nil;
  34.   node w;
  35.   point Q;
  36.   forall_adj_nodes(w,v)
  37.     if (s.intersection(DAG[w]->s,Q)) 
  38.     { u = w;
  39.       break;
  40.      }
  41.   DAG.init_adj_iterator(v);
  42.   return u;
  43. }
  44.  
  45.  
  46.  
  47. main()
  48.  
  49.   window W;
  50.  
  51.   W.init(0,1000,0);
  52.  
  53.  
  54.   point A,B,C;
  55.  
  56.   W >> A; W << A;
  57.   W >> B; W << B;
  58.   W >> C; W << C;
  59.  
  60.   // we start with a triangle
  61.  
  62.   segment sa(A,B);
  63.   segment sb(B,C);
  64.   segment sc(C,A);
  65.  
  66.   W << sa << sb << sc;
  67.  
  68.   if (sa.angle(sb) < 0) 
  69.   { sa = segment(A,C);
  70.     sb = segment(C,B);
  71.     sc = segment(B,A);
  72.    }
  73.  
  74.   node root = NEW_NODE(segment(A,A));
  75.   node    a = NEW_NODE(sa);
  76.   node    b = NEW_NODE(sb);
  77.   node    c = NEW_NODE(sc);
  78.  
  79.   //DAG edges
  80.  
  81.   DAG.new_edge(root,a,0);
  82.   DAG.new_edge(root,b,0);
  83.   DAG.new_edge(root,c,0);
  84.  
  85.   //POL is initialized to triangle (A,B,C);
  86.  
  87.   DAG[a]->it = POL.append(a);
  88.   DAG[b]->it = POL.append(b);
  89.   DAG[c]->it = POL.append(c);
  90.  
  91.   double x = (A.xcoord() + B.xcoord() + C.xcoord())/3;
  92.   double y = (A.ycoord() + B.ycoord() + C.ycoord())/3;
  93.  
  94.   point I(x,y);
  95.  
  96.   point P;
  97.  
  98.   while (W>>P)
  99.   { W << P;
  100.  
  101.     point   Q;
  102.  
  103.     segment S(P,I);
  104.  
  105.     node v = root;
  106.  
  107.     while (v!=nil && DAG.outdeg(v)!=0) v = next_segment(S,v);
  108.  
  109.     if (v==nil) continue;
  110.  
  111.      list_item it;
  112.  
  113.  
  114.      point   rtouch  = DAG[v]->s.start();
  115.      segment rtangent(P,rtouch);
  116.      node    w = v;
  117.  
  118.      it = DAG[w]->it;
  119.      while (rtangent.angle(DAG[w]->s) <= 0) 
  120.      { 
  121.        it = POL.cyclic_succ(it);
  122.        w = POL[it];
  123.        rtouch   = DAG[w]->s.start();
  124.        rtangent = segment(P,rtouch);
  125.       }
  126.  
  127.      point   ltouch   = DAG[v]->s.end();
  128.      segment ltangent(ltouch,P);
  129.      node    u = v;
  130.  
  131.      it = DAG[u]->it;
  132.      while (ltangent.angle(DAG[u]->s) >= 0) 
  133.      { it = POL.cyclic_pred(it);
  134.        u = POL[it];
  135.        ltouch   = DAG[u]->s.end();
  136.        ltangent = segment(ltouch,P);
  137.       }
  138.  
  139.  
  140.      node x = NEW_NODE(ltangent);
  141.      node y = NEW_NODE(rtangent);
  142.  
  143.      // draw tangents
  144.  
  145.      W << ltangent << rtangent;
  146.  
  147.  
  148.      it = POL.cyclic_succ(DAG[u]->it);
  149.      
  150.      while (it != DAG[w]->it)
  151.      { list_item i = it;
  152.        it = POL.cyclic_succ(it);
  153.        DAG.new_edge(POL[i],x);
  154.        DAG.new_edge(POL[i],y);
  155.        POL.del(i);
  156.       }
  157.      
  158.      DAG[x]->it = POL.insert(x,it,before);
  159.      DAG[y]->it = POL.insert(y,it,before);
  160.  
  161.  
  162.    }
  163.  
  164.   W.clear();
  165.   W.set_line_width(3);
  166.  
  167.   node v;
  168.  
  169.   forall(v,POL) W << DAG[v]->s;
  170.  
  171.   W.read_mouse();
  172.  
  173.  return 0;
  174. }
  175.  
  176.